/*
 * MyGWT User Extensions
 * 
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 * 
 * http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */
package net.mygwt.ux.client.widgets.impl;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import net.mygwt.ux.client.widgets.TextBox;

import com.google.gwt.core.client.JavaScriptObject;
import com.google.gwt.user.client.Element;
import com.google.gwt.user.client.Event;

/**
 * This is the implementation class for TextBox.
 * 
 * @author Damien Ferrand
 */
public class TextBoxImpl implements InputListener {
	/**
	 * The TextBox this implementation works for.
	 */
	protected TextBox textBox;
	/**
	 * Contains the list of listeners for input event.
	 */
	private List inputListeners;
	/**
	 * Used to store the javascript listener.
	 */
	private JavaScriptObject listener;

	/**
	 * The default constructor.
	 */
	public TextBoxImpl() {
		inputListeners = new ArrayList();
	}

	/**
	 * Stores the TextBox object this implementation works for.
	 * 
	 * @param textBox
	 *            the TextBox object
	 */
	public void setTextBox(TextBox textBox) {
		this.textBox = textBox;
	}

	/**
	 * Adds a listener for input event.
	 * 
	 * @param inputListener
	 *            the input event listener
	 */
	public void addInputListener(InputListener inputListener) {
		if (inputListeners.size() == 0) {
			registerInputListener(textBox.getElement());
		}
		inputListeners.add(inputListener);
	}

	/**
	 * This method is called when an input event fires. It calls the registered
	 * listeners.
	 * 
	 * @param e
	 *            the event
	 */
	private void fireInputEvent(Event e) {
		Iterator it = inputListeners.iterator();
		while (it.hasNext()) {
			InputListener il = (InputListener) it.next();
			il.onInput(e);
		}
	}

	/**
	 * Registers the javascript input listener.
	 * 
	 * @param element
	 *            the DOM element
	 */
	private native void registerInputListener(Element element) /*-{
		element.textBoxImpl = this;
		var listener = function(evt){
			var tbi = this.textBoxImpl;
			tbi.@net.mygwt.ux.client.widgets.impl.TextBoxImpl::fireInputEvent(Lcom/google/gwt/user/client/Event;)(evt);
		};
		this.@net.mygwt.ux.client.widgets.impl.TextBoxImpl::listener = listener;
		element.addEventListener('input',listener,false);
	}-*/;

	/**
	 * This method is called when the TextBox object is created.
	 */
	public void applyStyle() {
		registerListener();
	}

	/**
	 * Registers this object as an input listener.
	 */
	protected void registerListener() {
		addInputListener(this);
	}

	/**
	 * This method is called when an input event fires.
	 * 
	 * @param event
	 *            the DOM event
	 */
	public void onInput(Event event) {
		String previousValue = textBox.getPreviousValue();
		if ((textBox.getStyle() & TextBox.LOWERCASE) != 0) {
			textBox.setText(textBox.getText().toLowerCase());
		}
		if ((textBox.getStyle() & TextBox.UPPERCASE) != 0) {
			textBox.setText(textBox.getText().toUpperCase());
		}
		textBox.updatePreviousValue();
		textBox.checkValueChange(previousValue, textBox.getText());
	};

}
